package com.toolkit.util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author qdl
 * @descripton TODO  证件号码效验工具类
 * @Date 2023/12/21 10:43
 */
public class IDCardValidatorUtil {

    /**
     * 身份证号码
     */
    private static final String ID_CARD_REGEX = "^(\\d{17}[0-9Xx])$";
    /**
     * 护照
     */
    private static final String PASSPORT_NUMBER_PATTERN = "^[a-zA-Z0-9]{7,18}$";

    /**
     * 港澳通行证
     */
    private static final String HK_MACAO_PASS_REGEX = "^[A-Z]{1}[0-9]{10}$";
    public static boolean isValidIDCard(String idCard) {
        // 编译正则表达式
        Pattern pattern = Pattern.compile(ID_CARD_REGEX);

        // 匹配器
        Matcher matcher = pattern.matcher(idCard);

        // 进行匹配
        if (!matcher.matches()) {
            return false;
        }

        // 获取前17位
        String idCard17 = idCard.substring(0, 17);

        // 验证前17位是否为数字
        if (!idCard17.matches("\\d{17}")) {
            return false;
        }

        // 验证出生日期
        String year = idCard17.substring(6, 10);
        String month = idCard17.substring(10, 12);
        String day = idCard17.substring(12, 14);

        if (!isValidDate(year, month, day)) {
            return false;
        }

        // 验证校验码
        if (!isValidVerifyCode(idCard)) {
            return false;
        }

        return true;
    }

    private static boolean isValidDate(String year, String month, String day) {
        try {
            int y = Integer.parseInt(year);
            int m = Integer.parseInt(month);
            int d = Integer.parseInt(day);

            if (m < 1 || m > 12 || d < 1 || d > 31) {
                return false;
            }

            if ((m == 4 || m == 6 || m == 9 || m == 11) && d > 30) {
                return false;
            }

            if (m == 2) {
                if ((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0)) {
                    if (d > 29) {
                        return false;
                    }
                } else {
                    if (d > 28) {
                        return false;
                    }
                }
            }

            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    private static boolean isValidVerifyCode(String idCard) {
        String[] factors = {"7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2"};
        String[] verifyCodes = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};

        int sum = 0;

        for (int i = 0; i < 17; i++) {
            char c = idCard.charAt(i);
            int factor = Integer.parseInt(factors[i]);
            sum += (c - '0') * factor;
        }

        int remainder = sum % 11;
        String verifyCode = verifyCodes[remainder];

        char lastChar = idCard.charAt(17);

        return verifyCode.equalsIgnoreCase(String.valueOf(lastChar));
    }


    public static boolean isValidPassportNumber(String passportNumber) {
        Pattern pattern = Pattern.compile(PASSPORT_NUMBER_PATTERN);
        Matcher matcher = pattern.matcher(passportNumber);
        return matcher.matches();
    }

    public static boolean isValidHKMacaoPass(String passNumber) {
        // 编译正则表达式
        Pattern pattern = Pattern.compile(HK_MACAO_PASS_REGEX);

        // 匹配器
        Matcher matcher = pattern.matcher(passNumber);

        // 进行匹配
        return matcher.matches();
    }

    public static void main(String[] args) {
        if(isValidHKMacaoPass("H1234567890")){
            System.out.println(isValidHKMacaoPass("H1234567890")+ " 是有效的港澳通行证。");
        }else{
            System.out.println(isValidHKMacaoPass("H1234567890")+ " 不是有效的港澳通行证。");
        }
        if(isValidPassportNumber("E67503893")){
            System.out.println(isValidPassportNumber("E67503893") + " 是有效的护照号码。");
        }else{
            System.out.println(isValidPassportNumber("E67503893") + " 不是有效的护照号码。");
        }

        String idCard1 = "410523199606261037"; // 18位身份证号码
        String idCard2 = "350123880101234";    // 15位身份证号码

        if (isValidIDCard(idCard1)) {
            System.out.println(idCard1 + " 是有效的身份证号码。");
        } else {
            System.out.println(idCard1 + " 不是有效的身份证号码。");
        }

        if (isValidIDCard(idCard2)) {
            System.out.println(idCard2 + " 是有效的身份证号码。");
        } else {
            System.out.println(idCard2 + " 不是有效的身份证号码。");
        }
    }

}
